package be.fedict.eid.diagnostics.listeners;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;

import javax.swing.tree.DefaultMutableTreeNode;

import be.fedict.eid.diagnostics.DiagnosticTest;
import be.fedict.eid.diagnostics.DiagnosticTestManager;
import be.fedict.eid.diagnostics.helper.DataTuple;

public class ShellListener implements DiagnosticProgressListener {

	List<DiagnosticTest> tests = new ArrayList<DiagnosticTest>();
	DiagnosticTestManager testMgr;
	
	private void drawLine() {
		System.out.println("--------------------------------------------------------------------------------");
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		testMgr = (DiagnosticTestManager) arg0;
		DiagnosticTest test = (DiagnosticTest) arg1;
		
		switch (testMgr.getState()) {
		case BEGIN_TESTING:
			onStart();
			break;
		case END_TESTING:
			onFinish();
			break;
		case TEST_FINISHED:
			onTestFinished(test);
			break;
		case TEST_STARTED:
			onTestStarted(test);
			break;
		default:
			break;
		}
	}

	@Override
	public void onStart() {
		System.out.println("RUNNING eDT VERSION: 4.0.0-dev");	
		
	}

	@Override
	public void onTestStarted(DiagnosticTest test) {
		drawLine();
		System.out.println("[Diagnostic Test] " + test.getName());
	}

	@Override
	public void onTestFinished(DiagnosticTest test) {
		tests.add(test);
		
		System.out.print("[Result] ");
		System.out.print(verboseResult(test.getResult()));
		if (test.getResult().equals(DiagnosticTest.RESULT.FAILED))
			System.out.println(" - " + test.getProblem());
		else
			System.out.println();
	}

	private String verboseResult(DiagnosticTest.RESULT result) {
		switch (result) {
		case NONE:
			return "No result";
		case FAILED:
			return "Failed";
		case SUCCESS:
			return "Success";
		case SUCCESS_WITH_WARNINGS:
			return "Success (some problems encountered)";
		default:
			return "Unknown";
		}
	}
	
	private void printChildren(int depth, DefaultMutableTreeNode parentNode) {
		DefaultMutableTreeNode node;
		for (int i = 0; i < parentNode.getChildCount(); i++) {
			node = (DefaultMutableTreeNode) parentNode.getChildAt(i);
			for (int j = 0; j < depth; j++) {
				System.out.print("  ");
			}
			System.out.println(((DataTuple)node.getUserObject()).getKey() + ": " + ((DataTuple)node.getUserObject()).getValue());
			if (node.getChildCount()>0)
				printChildren(depth+1, node);
		}
		
	}
	
	@Override
	public void onFinish() {
		drawLine();
		System.out.println("Testing Finished");
		drawLine();	
		System.out.println("Summary:");
		for (DiagnosticTest test : tests) {
			System.out.println(" - " + test.getName() + ": " + verboseResult(test.getResult()));
		}
		drawLine();
		System.out.println("Data:");
		drawLine();
		printChildren(0, testMgr.getGatheredData());
		drawLine();
	}

}
